package org.x.usermod.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.x.usermod.dto.GetDeptUsersDTO;
import org.x.usermod.dto.ModifyDeptDTO;
import org.x.usermod.dto.CreateDeptDTO;
import org.x.usermod.entity.SysDeptEntity;
import org.x.usermod.entity.SysUser;
import org.x.usermod.mapper.SysUserMapper;
import org.x.usermod.mapper.DeptMapper;
import org.x.usermod.service.DeptService;
import org.x.usermod.vo.DeptTreeVO;
import org.x.usermod.vo.GetDeptListVO;
import org.x.usermod.vo.GetDeptUsersVO;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, SysDeptEntity> implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private SysUserMapper userMapper;

    /**
     * 创建部门
     *
     * @param createDeptDTO
     * @return
     */
    @Override
    public Long createDept(CreateDeptDTO createDeptDTO) {
        SysDeptEntity sysDeptEntity = new SysDeptEntity();
        BeanUtils.copyProperties(createDeptDTO, sysDeptEntity);
        //获取当前登录用户的用户名
        Object loginId = StpUtil.getLoginId();
        //根据id查用户表中的用户名
        SysUser sysUserEntity = userMapper.selectOneById(Long.valueOf(loginId.toString()));
        sysDeptEntity.setCreatedBy(sysUserEntity.getUsername());
        //设置创建和修改时间
        sysDeptEntity.setCreatedTime(new Date());
        sysDeptEntity.setUpdatedTime(new Date());
        //添加部门
        deptMapper.insertSelective(sysDeptEntity);
        return sysDeptEntity.getId();
    }

    /**
     * 更新部门
     *
     * @param modifyDeptDTO
     */
    @Override
    public void modifyDept(ModifyDeptDTO modifyDeptDTO) {
        SysDeptEntity sysDeptEntity = new SysDeptEntity();
        BeanUtils.copyProperties(modifyDeptDTO, sysDeptEntity);
        sysDeptEntity.setUpdatedTime(new Date());
        long loginId = StpUtil.getLoginIdAsLong();
        //根据id查用户表中的用户名
        SysUser sysUserEntity = userMapper.selectOneById(loginId);
        sysDeptEntity.setUpdatedBy(sysUserEntity.getUsername());
        //更新部门
        deptMapper.update(sysDeptEntity);
    }

    /**
     * 删除部门
     *
     * @param id
     */
    @Override
    public void deleteDept(Long id) {
        deptMapper.deleteById(id);
        //TODO 删除子部门和部门下的用户，递归删除
    }

    /**
     * 分页查询部门列表
     * @param page 页码
     * @param size 每页数量
     * @param name 部门名称
     * @return
     */
    @Override
    public GetDeptListVO list(Integer page, Integer size, String name) {
        // 构建查询条件，添加name字段的模糊查询
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.orderBy("level");
        if (name != null && !name.trim().isEmpty()) {
            queryWrapper.like("name", name.trim());
        }
        // 执行分页查询
        Page<SysDeptEntity> pageResult = deptMapper.paginate(page, size, queryWrapper);
        long totalRow = pageResult.getTotalRow();
        //转换成list
        List<SysDeptEntity> sysDeptEntityList = pageResult.getRecords();
        //封装
        GetDeptListVO getDeptListVO = new GetDeptListVO();
        getDeptListVO.setSysDeptEntityList(sysDeptEntityList);
        getDeptListVO.setTotalRow(totalRow);
        return getDeptListVO;
    }

    /**
     * 查询部门详情
     *
     * @param id
     * @return
     */
    @Override
    public SysDeptEntity getDeptDetail(long id) {
        return deptMapper.selectOneById(id);
    }

    /**
     * 部门树
     * @return
     */
    /**
     * 思路：先查出所有部门的部门编号
     * 再根据部门编号查出所有子部门
     * 循环递归查询
     * 深度优先算法
     *
     * @return
     */
    @Override
    public List<DeptTreeVO> getDeepTree() {
        // 查询所有部门数据
        List<SysDeptEntity> allDeptEntities = deptMapper.selectAll();
        // 找到所有顶级部门（parent_id 为 0)
        List<DeptTreeVO> result = new ArrayList<>();
        for (SysDeptEntity deptEntity : allDeptEntities) {
            if (isTopLevelDept(deptEntity)) {
                // 判断是否是顶级部门，是的话构建部门树
                DeptTreeVO treeVO = buildDeptTree(deptEntity.getId(), allDeptEntities);
                result.add(treeVO);
            }
        }
        return result;
    }

    /**
     * 递归构建部门树
     * @param deptId        当前部门ID
     * @param allDeptEntities 所有部门数据
     * @return 包含当前部门及所有子部门的 DeptTreeVO
     */
    private DeptTreeVO buildDeptTree(Long deptId, List<SysDeptEntity> allDeptEntities) {
        // 1. 构建当前部门的 DeptTreeVO 基础信息
        //使用已经存好的实体避免多次查库
        SysDeptEntity currentDept = findDeptById(deptId, allDeptEntities);
        DeptTreeVO deptTreeVO = new DeptTreeVO();
        deptTreeVO.setDeptId(currentDept.getId());
        deptTreeVO.setName(currentDept.getName());
        //设置子部门集合列表
        deptTreeVO.setChildren(new ArrayList<>());

        // 2. 查询当前部门的直接子部门
        List<SysDeptEntity> childDeptEntities = findChildDeptsByParentId(deptId, allDeptEntities);
        for (SysDeptEntity childDept : childDeptEntities) {
            // 3. 递归构建子部门的树结构
            DeptTreeVO childTreeVO = buildDeptTree(childDept.getId(), allDeptEntities);
            // 4. 将子部门树添加到当前部门的 children 列表
            deptTreeVO.getChildren().add(childTreeVO);
        }

        return deptTreeVO;
    }

    /**
     * 根据部门ID从所有部门列表中找到对应的部门实体
     * @param deptId          部门ID
     * @param allDeptEntities 所有部门数据
     * @return 对应的 SysDeptEntity
     */
    private SysDeptEntity findDeptById(Long deptId, List<SysDeptEntity> allDeptEntities) {
        for (SysDeptEntity deptEntity : allDeptEntities) {
            if (deptEntity.getId().equals(deptId)) {
                return deptEntity;
            }
        }
        throw new RuntimeException("部门ID不存在");
    }

    /**
     * 根据父部门ID从所有部门列表中找到直接子部门
     * @param parentId       父部门ID
     * @param allDeptEntities 所有部门数据
     * @return 直接子部门列表
     */
    private List<SysDeptEntity> findChildDeptsByParentId(Long parentId, List<SysDeptEntity> allDeptEntities) {
        List<SysDeptEntity> childDepts = new ArrayList<>();
        for (SysDeptEntity deptEntity : allDeptEntities) {
            if (parentId.equals(deptEntity.getParentId())) {
                childDepts.add(deptEntity);
            }
        }
        return childDepts;
    }

    /**
     * 判断是否是顶级部门
     * @param deptEntity 部门实体
     * @return true-是顶级部门，false-不是
     */
    private boolean isTopLevelDept(SysDeptEntity deptEntity) {
        //  parent_id 为 0 表示顶级部门
        return  deptEntity.getParentId() == 0;
    }

    /**
     * 部门用户列表
     * @return
     */
    @Override
    public GetDeptUsersVO getDeptUserList(GetDeptUsersDTO getDeptUsersDTO) {
            Long deptId = getDeptUsersDTO.getDeptId();
            //查询用户
            QueryWrapper queryWrapper = QueryWrapper.create();
            queryWrapper.eq("dept_id",deptId);
            if (getDeptUsersDTO.getStatus() != null) {
                queryWrapper.eq("status",getDeptUsersDTO.getStatus());
            }
            Page<SysUser> sysUserPage = userMapper.paginate(getDeptUsersDTO.getPage(), getDeptUsersDTO.getSize(), queryWrapper);
            List<SysUser> userList = sysUserPage.getRecords();
            //封装数据
            GetDeptUsersVO getDeptUsersVO = new GetDeptUsersVO();
            getDeptUsersVO.setSysUserList(userList);
            getDeptUsersVO.setTotalRow(sysUserPage.getTotalRow());
            return getDeptUsersVO;
        }



}
